﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Kinect;

namespace KinectGhostHunter
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        KinectSensor kinect;

        short[] depthData;
        byte[] rgbBytes;
        Skeleton[] skeletons;

        public MainWindow()
        {
            InitializeComponent();

            this.Loaded += (s, e) =>
            {
                InitKinect();
            };

            this.Closed += (s, e) =>
                {
                    if (kinect != null)
                    {
                        kinect.Stop();
                        kinect.Dispose();
                        kinect = null;
                    }
                };
        }


        void InitKinect()
        {
            kinect = KinectSensor.KinectSensors.FirstOrDefault();
            if (kinect == null)
            {
                MessageBox.Show("kinect not available");
                return;
            }

            kinect.Start();

            kinect.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
            kinect.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
            kinect.SkeletonStream.Enable();

            kinect.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(kinect_AllFramesReady);

            booController.Kinect = kinect;
            booController.BooLaughElement = mediaElement;

        }

        void kinect_AllFramesReady(object sender, AllFramesReadyEventArgs e)
        {
            using (var depthFrame = e.OpenDepthImageFrame())
            {
                if (depthFrame == null)
                    return;
                if (depthData == null || depthData.Length != depthFrame.PixelDataLength)
                {
                    depthData = new short[depthFrame.PixelDataLength];
                }
                depthFrame.CopyPixelDataTo(depthData);
            }

            using (var rgbFrame = e.OpenColorImageFrame())
            {
                if (rgbFrame == null)
                    return;

                if (rgbBytes == null || depthData.Length != rgbFrame.PixelDataLength)
                {
                    rgbBytes = new byte[rgbFrame.PixelDataLength];
                }
                rgbFrame.CopyPixelDataTo(rgbBytes);
            }
            
            using (var skeletonFrame = e.OpenSkeletonFrame())
            {
                if (skeletonFrame == null)
                    return;

                if (skeletons == null || skeletons.Length != skeletonFrame.SkeletonArrayLength)
                {
                    skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
                }
                skeletonFrame.CopySkeletonDataTo(skeletons);
            }

            DisplayImage(rgbBytes);

            booController.UpdateBoos(skeletons);
        }

        private void DisplayImage(byte[] rgbBytes)
        {
            int rgbWidth = kinect.ColorStream.FrameWidth;
            int rgbHeight = kinect.ColorStream.FrameHeight;
            
            var source = BitmapSource.Create(rgbWidth, rgbHeight,
                                                96, 96,
                                                PixelFormats.Bgr32, null,
                                                rgbBytes, rgbWidth * 4);

            booController.KinectImageSource = source;
        }
    }
}
